home *** CD-ROM | disk | FTP | other *** search
- unit ShellBrowser;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
-
- type
- TBrowseSelectionChanged = procedure (Sender: TObject; var NewFolder: String; var Accept: Boolean) of Object;
-
- TShellDomain = ( sdDesktop, sdPrograms, sdControlPanel, sdPrinters, sdMyDocuments,
- sdFavorites, sdStartup, sdRecent, sdSendTo, sdRecycleBin,
- sdStartMenu, sdDrives, sdNetwork, sdNetHood, sdFonts );
-
- TBrowseOptions = ( FileSystemDirsOnly, DontGoBelowDomain,
- IncludeStatusText, ReturnSFAncestors,
- BrowseComputers, BrowsePrinters,
- BrowseFiles );
-
- TBrowseOptionSet = set of TBrowseOptions;
-
- TShellBrowser = class(TComponent)
- private
- { Private declarations }
- fLabelTitle: String;
- fFolderPath: String;
- fWindowTitle: String;
- fImageIndex: Integer;
- fStartDir: String;
- fReadOnlyStrProp: String;
- fReadOnlyIntProp: Integer;
- fDomain: TShellDomain;
- fCentred: Boolean;
- fOptions: TBrowseOptionSet;
- fSelectionChanged: TBrowseSelectionChanged;
- function DomainToIDL: Pointer;
- function GetFlags: UINT;
- procedure UpdateStatusText (Wnd: hWnd; const Selection: String);
- protected
- { Protected declarations }
- public
- { Public declarations }
- constructor Create (AOwner: TComponent); override;
- function Execute: Boolean;
- published
- { Published declarations }
- property LabelTitle: String read fLabelTitle write fLabelTitle;
- property Centred: Boolean read fCentred write fCentred default True;
- property FolderPath: String read fFolderPath write fReadOnlyStrProp;
- property WindowTitle: String read fWindowTitle write fWindowTitle;
- property StartDirectory: String read fStartDir write fStartDir;
- property ImageIndex: Integer read fImageIndex write fReadOnlyIntProp;
- property Domain: TShellDomain read fDomain write fDomain default sdDesktop;
- property Options: TBrowseOptionSet read fOptions write fOptions default [FileSystemDirsOnly];
- property OnSelectionChanged: TBrowseSelectionChanged read fSelectionChanged write fSelectionChanged;
- end;
-
- procedure Register;
-
- implementation
-
- uses FileCtrl, ShlObj, ActiveX; { ActiveX needed for IMalloc...sigh.... }
-
- procedure CentreWindow (Wnd: HWnd);
- var
- Rect: TRect;
- begin
- GetWindowRect (Wnd, Rect);
- SetWindowPos (Wnd, 0,
- (Screen.Width - Rect.Right + Rect.Left) div 2,
- (Screen.Height - Rect.Bottom + Rect.Top) div 2,
- 0, 0, swp_NoActivate or swp_NoSize or swp_NoZOrder);
- end;
-
- procedure TShellBrowser.UpdateStatusText (Wnd: hWnd; const Selection: String);
- var
- R: TRect;
- S: String;
- StatusWnd: hWnd;
- begin
- // Have we got a status label?
- if IncludeStatusText in fOptions then begin
- // WARNING: This requires carnal knowledge of SHELL32.DLL !
- // If Microsoft change the ID of the status label, the code
- // simply won't be able to trim the text to fit.
- S := Selection;
- StatusWnd := GetDlgItem (Wnd, $3743);
- if (StatusWnd <> 0) and IsWindowVisible (StatusWnd) then begin
- // We've got a status window. Should we trim the text?
- GetWindowRect (StatusWnd, R);
- S := MinimizeName (S, Application.MainForm.Canvas, R.Right - R.Left);
- end;
-
- SendMessage (Wnd, bffm_SetStatusText, 0, Integer (PChar (S)));
- end;
- end;
-
- function BrowserCallbackProc (Wnd: hWnd; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall;
- var
- Accept: Boolean;
- Selection: String;
- Buff: array [0..255] of Char;
- Self: TShellBrowser absolute lpData;
- begin
- with Self do case uMsg of
- bffm_Initialized:
-
- // This is the initialization call from the browse dialog.
- begin
- // Centre the dialog on screen if fCentred is True.
- if fCentred then CentreWindow (Wnd);
- // Set a custom dialog title if desired.
- if fWindowTitle <> '' then SetWindowText (Wnd, PChar (fWindowTitle));
- // Set an initial directory selection if desired
- if fStartDir <> '' then
- SendMessage (Wnd, bffm_SetSelection, Ord(True), Integer (PChar (fStartDir)));
- end;
-
- bffm_SelChanged:
-
- // This message is received whenever the folder changes
- // in the browser dialog. lParam is a pidl to the newly
- // selected folder.
- begin
- Accept := True;
-
- // Retrieve the current selection
- SHGetPathFromIDList (PItemIDList (lParam), Buff);
- Selection := StrPas (Buff);
-
- // Notify application of selection change?
- if Assigned (fSelectionChanged) then
- fSelectionChanged (Self, Selection, Accept);
-
- // Update status text
- UpdateStatusText (Wnd, Selection);
-
- // Enable/disable OK button as requested
- SendMessage (Wnd, bffm_EnableOK, 0, Ord (Accept));
- end;
- end;
-
- Result := 0;
- end;
-
- constructor TShellBrowser.Create (AOwner: TComponent);
- begin
- Inherited Create (AOwner);
- fCentred := True;
- fOptions := [FileSystemDirsOnly];
- end;
-
- function TShellBrowser.DomainToIDL: Pointer;
- var
- FolderNum: Integer;
- begin
- case fDomain of
- sdPrograms: FolderNum := csidl_Programs;
- sdControlPanel: FolderNum := csidl_Controls;
- sdPrinters: FolderNum := csidl_Printers;
- sdMyDocuments: FolderNum := csidl_Personal;
- sdFavorites: FolderNum := csidl_Favorites;
- sdStartup: FolderNum := csidl_Startup;
- sdRecent: FolderNum := csidl_Recent;
- sdSendTo: FolderNum := csidl_SendTo;
- sdRecycleBin: FolderNum := csidl_BitBucket;
- sdStartMenu: FolderNum := csidl_StartMenu;
- sdDrives: FolderNum := csidl_Drives;
- sdNetwork: FolderNum := csidl_Network;
- sdNetHood: FolderNum := csidl_NetHood;
- sdFonts: FolderNum := csidl_Fonts;
- else FolderNum := 0;
- end;
-
- if FolderNum = 0 then Result := Nil else
- SHGetSpecialFolderLocation (Application.Handle, FolderNum, PItemIDList (Result));
- end;
-
- function TShellBrowser.GetFlags: UINT;
- begin
- Result := 0;
- if FileSystemDirsOnly in fOptions then Result := Result or bif_ReturnOnlyFSDirs;
- if DontGoBelowDomain in fOptions then Result := Result or bif_DontGoBelowDomain;
- if IncludeStatusText in fOptions then Result := Result or bif_StatusText;
- if ReturnSFAncestors in fOptions then Result := Result or bif_ReturnFSAncestors;
- if BrowseComputers in fOptions then Result := Result or bif_BrowseForComputer;
- if BrowsePrinters in fOptions then Result := Result or bif_BrowseForPrinter;
- if BrowseFiles in fOptions then Result := Result or bif_BrowseIncludeFiles;
- end;
-
- function TShellBrowser.Execute: Boolean;
- var
- pidl: PItemIDList;
- ShellMalloc: IMalloc;
- BrowseInfo: TBrowseInfo;
- Buff: array [0..255] of Char;
- begin
- Result := False;
- if (ShGetMalloc (ShellMalloc) = S_OK) and (ShellMalloc <> Nil) then begin
- BrowseInfo.hwndOwner := Application.Handle;
- BrowseInfo.pidlRoot := DomainToIDL;
- BrowseInfo.pszDisplayName := Nil;
- BrowseInfo.lpszTitle := PChar (fLabelTitle);
- BrowseInfo.ulFlags := GetFlags;
- BrowseInfo.lpfn := BrowserCallbackProc;
- BrowseInfo.lParam := Integer (Self);
-
- pidl := SHBrowseForFolder (BrowseInfo);
- if pidl = Nil then fFolderPath := '' else begin
- Result := SHGetPathFromIDList (pidl, Buff);
- fFolderPath := StrPas (Buff);
- fImageIndex := BrowseInfo.iImage;
- ShellMalloc.Free (pidl);
- end;
- end;
- end;
-
- procedure Register;
- begin
- RegisterComponents ('The X Factor', [TShellBrowser]);
- end;
-
- end.
-